/**
 * 
 */
package com.cmcc.pcap.jpcap.udp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.cmcc.packet.entity.XdrEntity;
import com.cmcc.pcap.jpcap.capture.HandlerManager;
import com.cmcc.pcap.jpcap.capture.JCaptures;



/**
 * @author Amish
 * @date 2018年12月24日 下午3:44:39
 * 
 */
public class UdpProtocolDispatcher implements Runnable{
	public static Logger logger = LogManager.getLogger(UdpProtocolDispatcher.class);
	
    private HashMap<String, UdpProtocolHandler> hashmap;
	private String taskId;
	
	UdpConnectionCache udpConnectionCache;
	JCaptures jCaptures;
	
	public UdpProtocolDispatcher(JCaptures jCaptures,UdpConnectionCache udpConnectionCache){
		this.jCaptures = jCaptures;
		this.udpConnectionCache = udpConnectionCache;
		this.hashmap = new HashMap<>();
	}
	
    /**
     * 用于识别UDP的应用层协议，并返回对应的Handler
     * @return
     */
    private UdpProtocolHandler distinguishTcpProtocol(UdpConnection udpConnection){
    	//根据TcpProtocolFilter的结果，直接判断TcpConnection中的对应成员变量
    	switch(udpConnection.protocol){
    	case UDP:{
    		logger.debug("this is return udp handler !");
    		if(hashmap.containsKey("UDP")) {
    			return hashmap.get("UDP");
    		}
    		else {
				try {
					hashmap.put("UDP", HandlerManager.getUdpHandler());
				} catch (IllegalAccessException | InstantiationException e) {
					logger.error(e.getMessage());
				}
				return hashmap.get("UDP");
    		}
//    	    return new HttpHandler();
    	}

    	default:
    		//return new DefaultProtocolHandler();
    		logger.info("Can not dispatcher protocol : "+udpConnection.protocol.name());
    		return null;
    	}
    }

	@Override
	public void run() {
		
		while(true){
			
			ArrayList<UdpConnection> al  = udpConnectionCache.getUdpConnection();//此处由于同步 可能阻塞
            if(al.size() != 0){
            	logger.info("Get Udp Connection num : "+al.size());
            }
			for(UdpConnection udpConnection : al){
				try{
					UdpProtocolHandler udpProtocolHandler = distinguishTcpProtocol(udpConnection);
					if(udpProtocolHandler != null){
						List<XdrEntity> xdrList = udpProtocolHandler.handle(udpConnection,taskId);
						if(xdrList!=null&&xdrList.size()!=0) {
							jCaptures.udpcallBack.action(xdrList);
						}
					}else{
						logger.error("Can not get the protocol handler");
					}
					
					
				}catch(Exception e){
					logger.error(e.getCause(),e);
				}finally {
					udpConnectionCache.handledPacketNum.addAndGet(udpConnection.al.size());
				}
			}
			
		}
		
	}
	
	public String getTaskId() {
	    return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

}
